package com.yt.fras.controller;


import com.alibaba.excel.EasyExcel;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.yt.fras.listener.ExcelListener;
import com.yt.fras.pojo.base.JsonResult;
import com.yt.fras.pojo.base.LoginUser;
import com.yt.fras.pojo.base.UserInputExcel;
import com.yt.fras.pojo.entity.GroupUser;
import com.yt.fras.pojo.entity.ManagementGroup;
import com.yt.fras.pojo.model.UserInfo;
import com.yt.fras.service.ExcelService;
import com.yt.fras.service.GroupUserService;
import com.yt.fras.service.ManagementGroupService;
import com.yt.fras.service.UserService;
import com.yt.fras.utils.ResultTool;
import io.swagger.annotations.*;
import org.apache.commons.lang3.RandomStringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;

/**
 * <p>
 * 用户管理组模块
 * </p>
 *
 * @author yt
 * @since 2021-10-25
 */
@RestController
@Api(tags = "用户管理组模块")
@RequestMapping("/fras")
public class GroupController {

    @Autowired
    private UserService userService;

    @Autowired
    private ManagementGroupService managementGroupService;

    @Autowired
    private GroupUserService groupUserService;

    @Autowired
    private ThreadPoolTaskExecutor applicationTaskExecutor;

    @Autowired
    private ExcelService excelService;

    /**
     * 获取用户所在的所有用户组
     *
     * @return
     */
    @GetMapping("/user/userGroups")
    @ApiOperation(value = "获取用户所在的所有用户组")
    @ApiResponses({
            @ApiResponse(code = 200, message = "获取成功！"),
            @ApiResponse(code = 500, message = "系统出现错误~")
    })
    public String getUserGroups() {
        LoginUser loginUser = (LoginUser) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
        JsonResult result = ResultTool.success(managementGroupService.getGroupsByUserId(loginUser.getId()));
        result.setMsg("获取成功！");
        return JSON.toJSONString(result);
    }

    /**
     * 获取管理员管理的所有用户组
     *
     * @return
     */
    @GetMapping("/admin/adminGroups")
    @ApiOperation(value = "获取管理员管理的所有用户组")
    @ApiResponses({
            @ApiResponse(code = 200, message = "获取成功！"),
            @ApiResponse(code = 500, message = "系统出现错误~")
    })
    public String getAdminGroups() {
        LoginUser loginUser = (LoginUser) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
        JsonResult result = ResultTool.success(managementGroupService.getGroupListByAdminId(loginUser.getId()));
        result.setMsg("获取成功！");
        return JSON.toJSONString(result);
    }

    /**
     * 管理员添加用户组
     *
     * @param name
     * @param description
     * @return
     */
    @PostMapping("/admin/group/{name}/{description}/{picture}")
    @ApiOperation(value = "管理员添加用户组")
    @ApiResponses({
            @ApiResponse(code = 0, message = "添加失败！"),
            @ApiResponse(code = 200, message = "添加成功！"),
            @ApiResponse(code = 500, message = "系统出现错误~")
    })
    @ApiImplicitParams({
            @ApiImplicitParam(paramType = "path", name = "description", value = "用户组描述", required = true),
            @ApiImplicitParam(paramType = "path", name = "name", value = "用户组组名", required = true),
            @ApiImplicitParam(paramType = "path", name = "picture", value = "图片标识", required = true),
    })
    public String addGroup(@PathVariable String name, @PathVariable String description,@PathVariable Integer picture) {
        LoginUser loginUser = (LoginUser) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
        JsonResult result;

        ManagementGroup managementGroup = new ManagementGroup();
        managementGroup.setCount(0);
        managementGroup.setAdminId(loginUser.getId());
        managementGroup.setName(name);
        managementGroup.setDescription(description);
        managementGroup.setPicture(picture);
        managementGroup.setCode(RandomStringUtils.randomAlphanumeric(6).toUpperCase());

        if (managementGroupService.save(managementGroup)) {
            result = ResultTool.success();
            result.setMsg("添加成功！");
        } else {
            result = ResultTool.fail();
            result.setMsg("添加失败！");
        }
        return JSON.toJSONString(result);
    }

    /**
     * 管理员修改用户组信息
     *
     * @param name
     * @param description
     * @param groupId
     * @return
     */
    @PutMapping("/admin/group/{groupId}/{name}/{description}")
    @ApiOperation(value = "管理员修改用户组信息")
    @ApiResponses({
            @ApiResponse(code = 0, message = "修改失败！"),
            @ApiResponse(code = 200, message = "修改成功！"),
            @ApiResponse(code = 500, message = "系统出现错误~")
    })
    @ApiImplicitParams({
            @ApiImplicitParam(paramType = "path", name = "groupId", value = "用户用户组Id", required = true),
            @ApiImplicitParam(paramType = "path", name = "description", value = "用户组描述", required = true),
            @ApiImplicitParam(paramType = "path", name = "name", value = "用户组组名", required = true)
    })
    public String updateGroup(@PathVariable String groupId, @PathVariable String name, @PathVariable String description) {
        JsonResult result;
        LoginUser loginUser = (LoginUser) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
        ManagementGroup managementGroup = managementGroupService.getById(groupId);

        if (managementGroup != null && managementGroup.getAdminId().equals(loginUser.getId())) {
            managementGroup.setName(name);
            managementGroup.setDescription(description);

            if (managementGroupService.updateById(managementGroup)) {
                result = ResultTool.success();
                result.setMsg("修改成功！");
            } else {
                result = ResultTool.fail();
                result.setMsg("修改失败！");
            }
        } else {
            result = ResultTool.fail();
            result.setMsg("用户组不存在！");
        }

        return JSON.toJSONString(result);
    }

    /**
     * 管理员删除用户组
     *
     * @param groupId
     * @return
     */
    @DeleteMapping("/admin/group/{groupId}")
    @ApiOperation(value = "管理员删除用户组")
    @ApiResponses({
            @ApiResponse(code = 0, message = "删除失败！"),
            @ApiResponse(code = 200, message = "删除成功！"),
            @ApiResponse(code = 500, message = "系统出现错误~")
    })
    @ApiImplicitParams({
            @ApiImplicitParam(paramType = "path", name = "groupId", value = "用户组Id", required = true),
    })
    public String deleteGroup(@PathVariable String groupId) {
        JsonResult result;
        LoginUser loginUser = (LoginUser) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
        ManagementGroup managementGroup = managementGroupService.getById(groupId);

        if (managementGroup != null && managementGroup.getAdminId().equals(loginUser.getId())) {
            if (managementGroupService.removeById(managementGroup)) {
                if (groupUserService.deleteGroupUserByGroupId(groupId)) {
                    result = ResultTool.success();
                    result.setMsg("删除成功！");
                } else {
                    result = ResultTool.fail();
                    result.setMsg("删除失败！");
                }
            } else {
                result = ResultTool.fail();
                result.setMsg("删除失败！");
            }
        } else {
            result = ResultTool.fail();
            result.setMsg("用户组不存在！");
        }

        return JSON.toJSONString(result);
    }

    /**
     * 管理员获取管理组的所有成员
     *
     * @param groupId
     * @return
     */
    @GetMapping("/admin/getUserInfoListByGroup/{groupId}")
    @ApiOperation(value = "管理员获取管理组的所有成员")
    @ApiResponses({
            @ApiResponse(code = 200, message = "获取成功！"),
            @ApiResponse(code = 500, message = "系统出现错误~")
    })
    @ApiImplicitParams({
            @ApiImplicitParam(paramType = "path", name = "groupId", value = "用户组Id", required = true)
    })
    public String getUserInfoListByGroup(@PathVariable String groupId) {
        JsonResult result;
        LoginUser loginUser = (LoginUser) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
        ManagementGroup managementGroup = managementGroupService.getById(groupId);

        if (managementGroup != null && managementGroup.getAdminId().equals(loginUser.getId())) {
            result = ResultTool.success(userService.getUserInfoListByGroup(groupId));
            result.setMsg("获取成功！");
        } else {
            result = ResultTool.fail();
            result.setMsg("用户组不存在！");
        }
        result.setMsg("获取成功！");
        return JSON.toJSONString(result);
    }

    /**
     * 管理员删除用户组成员
     *
     * @param groupId
     * @param userId
     * @return
     */
    @DeleteMapping("/admin/groupUser/{groupId}/{userId}")
    @ApiOperation(value = "管理员删除用户组成员")
    @ApiResponses({
            @ApiResponse(code = 0, message = "删除失败！"),
            @ApiResponse(code = 200, message = "删除成功！"),
            @ApiResponse(code = 500, message = "系统出现错误~")
    })
    @ApiImplicitParams({
            @ApiImplicitParam(paramType = "path", name = "groupId", value = "用户组Id", required = true),
            @ApiImplicitParam(paramType = "path", name = "userId", value = "用户Id", required = true)
    })
    public String deleteUser(@PathVariable String groupId, @PathVariable String userId) {
        JsonResult result;
        LoginUser loginUser = (LoginUser) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
        ManagementGroup managementGroup = managementGroupService.getById(groupId);

        if (userService.getById(userId) == null) {
            result = ResultTool.fail();
            result.setMsg("用户不存在！");
            return JSON.toJSONString(result);
        }

        if (managementGroup != null && managementGroup.getAdminId().equals(loginUser.getId())) {
            if (groupUserService.deleteUser(groupId, userId)) {
                managementGroup.setCount(managementGroup.getCount() - 1);
                if (managementGroupService.updateById(managementGroup)) {
                    result = ResultTool.success();
                    result.setMsg("删除成功！");
                } else {
                    result = ResultTool.fail();
                    result.setMsg("删除失败！");
                }
            } else {
                result = ResultTool.fail();
                result.setMsg("删除失败！");
            }
        } else {
            result = ResultTool.fail();
            result.setMsg("用户组不存在！");
        }

        return JSON.toJSONString(result);
    }

    /**
     * 管理员添加用户组成员
     *
     * @param groupId
     * @param userId
     * @return
     */
    @PostMapping("/admin/groupUser/{groupId}/{userId}")
    @ApiOperation(value = "管理员添加用户组成员")
    @ApiResponses({
            @ApiResponse(code = 0, message = "添加失败！"),
            @ApiResponse(code = 200, message = "添加成功！"),
            @ApiResponse(code = 500, message = "系统出现错误~")
    })
    @ApiImplicitParams({
            @ApiImplicitParam(paramType = "path", name = "groupId", value = "用户组Id", required = true),
            @ApiImplicitParam(paramType = "path", name = "userId", value = "用户Id", required = true)
    })
    public String addUser(@PathVariable String groupId, @PathVariable String userId) {
        JsonResult result;
        LoginUser loginUser = (LoginUser) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
        ManagementGroup managementGroup = managementGroupService.getById(groupId);

        if (userService.getById(userId) == null) {
            result = ResultTool.fail();
            result.setMsg("用户不存在！");
            return JSON.toJSONString(result);
        }

        if (managementGroup != null && managementGroup.getAdminId().equals(loginUser.getId())) {
            if (managementGroup.getAdminId().equals(userId)) {
                result = ResultTool.fail();
                result.setMsg("无法添加自己");
            } else {
                GroupUser groupUser = new GroupUser();
                groupUser.setGroupId(groupId);
                groupUser.setUserId(userId);

                QueryWrapper<GroupUser> wrapper = new QueryWrapper<>();
                wrapper.eq("user_id", userId)
                        .eq("group_id", groupId);

                if (groupUserService.getOne(wrapper) == null) {
                    if (groupUserService.save(groupUser)) {
                        managementGroup.setCount(managementGroup.getCount() + 1);
                        managementGroupService.updateById(managementGroup);
                        result = ResultTool.success();
                        result.setMsg("添加成功！");
                    } else {
                        result = ResultTool.fail();
                        result.setMsg("添加失败！");
                    }
                } else {
                    result = ResultTool.fail();
                    result.setMsg("添加失败！用户已存在");
                }

            }
        } else {
            result = ResultTool.fail();
            result.setMsg("用户组不存在！");
        }

        return JSON.toJSONString(result);
    }

    /**
     * 管理员批量添加用户组成员
     *
     * @param groupId
     * @return
     * @throws IOException
     */
    @PostMapping("/superadmin/groupUsers/{groupId}")
    @ApiOperation(value = "管理员批量添加用户组成员")
    @ApiResponses({
            @ApiResponse(code = 0, message = "添加失败！"),
            @ApiResponse(code = 200, message = "添加成功！"),
            @ApiResponse(code = 500, message = "系统出现错误~")
    })
    @ApiImplicitParams({
            @ApiImplicitParam(paramType = "path", name = "groupId", value = "用户组Id", required = true),
            @ApiImplicitParam(paramType = "body", name = "file", value = "Excel文件", required = true)
    })
    public String addUsers(@PathVariable String groupId, @RequestParam("file") MultipartFile file) {
        JsonResult result;
        LoginUser loginUser = (LoginUser) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
        ManagementGroup managementGroup = managementGroupService.getById(groupId);

        if (managementGroup != null && managementGroup.getAdminId().equals(loginUser.getId())) {
            try {
                EasyExcel.read(file.getInputStream(), UserInputExcel.class, new ExcelListener(excelService, groupId)).sheet().doRead();
                result = ResultTool.success();
                result.setMsg("添加成功！");
            } catch (Exception e) {
                e.printStackTrace();
                result = ResultTool.fail();
                result.setMsg("添加失败！");
            }
        } else {
            result = ResultTool.fail();
            result.setMsg("用户组不存在！");
        }


        return JSON.toJSONString(result);
    }

    /**
     * 管理员搜索用户
     *
     * @param keyword
     * @return
     * @throws ExecutionException
     * @throws InterruptedException
     */
    @PostMapping("/admin/searchUsers/{keyword}")
    @ApiOperation(value = "管理员搜索用户")
    @ApiResponses({
            @ApiResponse(code = 200, message = "获取成功！"),
            @ApiResponse(code = 500, message = "系统出现错误~")
    })
    @ApiImplicitParams({
            @ApiImplicitParam(paramType = "path", name = "keyword", value = "关键词", required = true)
    })
    public String searchUsers(@PathVariable String keyword) throws ExecutionException, InterruptedException {
        JsonResult result;
        List<UserInfo> userInfoList = userService.getUserInfoList();
        List<UserInfo> userInfos = new ArrayList<>();

        CompletableFuture<Void> userInfosFuture = CompletableFuture.runAsync(() -> {

            userInfoList.forEach(userInfo -> {
                if (Optional.ofNullable(userInfo.getUsername()).isPresent()) {
                    if (userInfo.getUsername().contains(keyword)) {
                        userInfos.add(userInfo);
                    }
                }
                if (Optional.ofNullable(userInfo.getName()).isPresent()) {
                    if (userInfo.getName().contains(keyword)) {
                        userInfos.add(userInfo);
                    }
                }
            });
        }, applicationTaskExecutor);

        CompletableFuture.allOf(userInfosFuture).get();
        if (userInfos.size() > 0) {
            result = ResultTool.success(userInfos);
            result.setMsg("获取成功！");
        } else {
            result = ResultTool.fail();
            result.setMsg("无相关数据！");
        }

        return JSON.toJSONString(result);
    }

    /**
     * 用户通过标识码添加用户组
     *
     * @param code
     * @return
     */
    @PostMapping("/user/joinGroup/{code}")
    @ApiOperation(value = "用户通过标识码添加用户组")
    @ApiResponses({
            @ApiResponse(code = 0, message = "添加失败！"),
            @ApiResponse(code = 200, message = "添加成功！"),
            @ApiResponse(code = 500, message = "系统出现错误~")
    })
    @ApiImplicitParams({
            @ApiImplicitParam(paramType = "path", name = "code", value = "标识码", required = true)
    })
    public String joinGroup(@PathVariable String code) {
        JsonResult result;

        LoginUser loginUser = (LoginUser) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
        ManagementGroup managementGroup = managementGroupService.getGroupByCode(code);

        if (managementGroup == null) {
            result = ResultTool.fail();
            result.setMsg("用户组不存在！");
            return JSON.toJSONString(result);
        }

        if (loginUser.getId().equals(managementGroup.getAdminId())) {
            result = ResultTool.fail();
            result.setMsg("无法加入自己的管理组");
        } else {

            GroupUser groupUser = new GroupUser();
            groupUser.setGroupId(managementGroup.getId());
            groupUser.setUserId(loginUser.getId());

            QueryWrapper<GroupUser> wrapper = new QueryWrapper<>();
            wrapper.eq("user_id", loginUser.getId())
                    .eq("group_id", managementGroup.getId());
            if (groupUserService.getOne(wrapper) == null) {
                if (groupUserService.save(groupUser)) {
                    managementGroup.setCount(managementGroup.getCount() + 1);
                    managementGroupService.updateById(managementGroup);
                    result = ResultTool.success();
                    result.setMsg("添加成功！");
                } else {
                    result = ResultTool.fail();
                    result.setMsg("添加失败！");
                }
            } else {
                result = ResultTool.fail();
                result.setMsg("添加失败！用户已存在");
            }
        }

        return JSON.toJSONString(result);
    }

    /**
     * 用户退出用户组
     *
     * @param groupId
     * @return
     */
    @PostMapping("/user/leaveGroup/{groupId}")
    @ApiOperation(value = "用户退出用户组")
    @ApiResponses({
            @ApiResponse(code = 0, message = "退出失败！"),
            @ApiResponse(code = 200, message = "退出成功！"),
            @ApiResponse(code = 500, message = "系统出现错误~")
    })
    @ApiImplicitParams({
            @ApiImplicitParam(paramType = "path", name = "groupId", value = "用户组Id", required = true)
    })
    public String leaveGroup(@PathVariable String groupId) {
        JsonResult result;

        LoginUser loginUser = (LoginUser) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
        ManagementGroup managementGroup = managementGroupService.getById(groupId);

        if (managementGroup != null) {
            QueryWrapper<GroupUser> wrapper = new QueryWrapper<>();
            wrapper.eq("user_id", loginUser.getId())
                    .eq("group_id", managementGroup.getId());
            GroupUser groupUser = groupUserService.getOne(wrapper);
            if (groupUser == null) {
                result = ResultTool.fail();
                result.setMsg("当前用户没有加入该组！");
            } else {
                if (groupUserService.removeById(groupUser.getId())) {
                    managementGroup.setCount(managementGroup.getCount() - 1);
                    if (managementGroupService.updateById(managementGroup)) {
                        result = ResultTool.success();
                        result.setMsg("退出成功！");
                    } else {
                        result = ResultTool.fail();
                        result.setMsg("退出失败！");
                    }
                } else {
                    result = ResultTool.fail();
                    result.setMsg("退出失败！");
                }
            }
        } else {
            result = ResultTool.fail();
            result.setMsg("用户组不存在！");
        }

        return JSON.toJSONString(result);
    }

    /**
     * 根据用户用户组Id获取用户组信息
     *
     * @return
     */
    @GetMapping("/admin/adminGroup/{groupId}")
    @ApiOperation(value = "根据用户用户组Id获取用户组信息(管理员获取)")
    @ApiResponses({
            @ApiResponse(code = 200, message = "获取成功！"),
            @ApiResponse(code = 500, message = "系统出现错误~")
    })
    public String getAdminGroup(@PathVariable String groupId) {
        JsonResult result;
        LoginUser loginUser = (LoginUser) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
        ManagementGroup managementGroup = managementGroupService.getById(groupId);

        if (managementGroup != null && managementGroup.getAdminId().equals(loginUser.getId())) {
            result = ResultTool.success(managementGroupService.getGroupById(groupId));
            result.setMsg("获取成功！");
        } else {
            result = ResultTool.fail();
            result.setMsg("用户组不存在！");
        }

        return JSON.toJSONString(result);
    }

    /**
     * 根据用户用户组Id获取用户组信息
     *
     * @return
     */
    @GetMapping("/user/userGroup/{groupId}")
    @ApiOperation(value = "根据用户用户组Id获取用户组信息(用户获取)")
    @ApiResponses({
            @ApiResponse(code = 200, message = "获取成功！"),
            @ApiResponse(code = 500, message = "系统出现错误~")
    })
    public String getUserGroup(@PathVariable String groupId) {
        JsonResult result;
        LoginUser loginUser = (LoginUser) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
        ManagementGroup managementGroup = managementGroupService.getById(groupId);
        QueryWrapper<GroupUser> wrapper = new QueryWrapper<>();
        wrapper.eq("user_id", loginUser.getId())
                .eq("group_id", managementGroup.getId());
        if (managementGroup != null && groupUserService.getOne(wrapper) != null) {
            result = ResultTool.success(managementGroupService.getGroupById(groupId));
            result.setMsg("获取成功！");
        } else {
            result = ResultTool.fail();
            result.setMsg("用户组不存在！");
        }

        return JSON.toJSONString(result);
    }

}

